package ucd.csi.comp30220.fall2011.oteop.flughafen.impl;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;

import ucd.csi.comp30220.fall2011.oteop.OTEOP;
import ucd.csi.comp30220.fall2011.oteop.flight.FlightInfo;
import ucd.csi.comp30220.fall2011.oteop.flughafen.Airport;
import ucd.csi.comp30220.fall2011.oteop.flughafen.AirportInfo;
import ucd.csi.comp30220.fall2011.oteop.util.PortFinder;

public class RemoteAirportServer extends UnicastRemoteObject implements RemoteAirport {
    
    private static final long serialVersionUID = -1925746905283759486L;

    private Registry registry;
    private AirportInfo info;
    private transient JmDNS jmDNS;
    private transient ServiceInfo serviceInfo;
    private transient Dispatcher dispatcher = new Dispatcher();
    
    public RemoteAirportServer(AirportInfo info) throws Exception {
        this.info = info;
        int port = 0;
        while (registry == null) {
            try {
                port = PortFinder.getNextAvailable();
                registry = LocateRegistry.createRegistry(port);
                Thread.sleep(100);
            } catch (Exception e) {
                Thread.sleep(100);
            }
        }
        registry.rebind(info.getCode(), this);
        
        jmDNS = JmDNS.create();
        serviceInfo = ServiceInfo.create(
            OTEOP.JMDNS_TYPE_TCP_LOCAL, 
            info.getCode(), 
            Airport.JMDNS_SUB_TYPE, 
            port, 
            info.getName());
        
        jmDNS.registerService(serviceInfo);
        
        System.err.println("Registered: " +info +" on " +port);
    }
        
    public void unregister() throws Exception {
        jmDNS.unregisterService(serviceInfo);
        registry.unbind(info.getCode());
    }

    public AirportInfo getInfo() throws RemoteException {
        return info;
    }

    public void acceptFlight(FlightInfo flightInfo) throws RemoteException {
        // Add listener to flight, tell airline when it lands
        System.err.println("## Accepted flight: " +flightInfo.getNumber());
    }
    
    public void dispatchFlight(FlightInfo flightInfo) throws RemoteException {
        dispatcher.acceptFlight(flightInfo);
    }
}
